package com.googlecode.rjm.model.journal;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.HibernateException;
import org.hibernate.annotations.DiscriminatorFormula;
import org.hibernate.annotations.ForceDiscriminator;

import com.googlecode.rjm.model.Persistent;
import com.googlecode.rjm.util.HibernateUtil;


@Entity
@Table(name="journal_details")
@DiscriminatorFormula(value="concat( property , '#' , prop_key)")
@ForceDiscriminator
public abstract class JournalDetail<T> extends Persistent {
	
	@Id
	private Integer id;
	
	@Transient
	@JoinColumn(name="journal_id")
	private Journal journal;
	
	private String value;
	
	@Column(name="old_value")
	private String oldValue;
	
	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Journal getJournal() {
		return this.journal;
	}

	public void setJournal(Journal journal) {
		this.journal = journal;
	}

	public String getValue() {
		return this.value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getOldValue() {
		return this.oldValue;
	}

	public void setOldValue(String oldValue) {
		this.oldValue = oldValue;
	}
	
	@Override
	public String toString() {
		return oldValue + "=>" + value;
	}
	
	public abstract T getTypedValue();

	public abstract T getOldTypedValue();
	
	/**
	 * Load an object given an id.
	 * 
	 * @param stringValue
	 *            The id value as String.
	 * @param clazz
	 *            The object class.
	 * @return The object with given id.
	 */
	@SuppressWarnings("unchecked")
	protected T loadObjectFromId(String stringValue, Class<T> clazz) throws HibernateException, NumberFormatException {
		try {
			return (T) HibernateUtil.getCurrentSession().load(clazz, Integer.parseInt(stringValue));
		} catch (HibernateException e) {
			throw new IllegalStateException("Could not load object: " + e.getMessage(), e);
		} catch (NumberFormatException e) {
			return null;
		}
	}

}
